#ifndef SYNC_ALG_H
#define SYNC_ALG_H

#include <ImageType.hpp>
#include <deque>
#include <vector>
#include <list>
#include <thread>
#include <functional>
#include <mutex>
#include <condition_variable>
#include <map>
#include <pthread.h>

struct BigImageType
{
  ImageType data;
  int camera_index;
};

struct bottleItemType
{
  std::vector<std::list<BigImageType>::iterator> dataRef;
  unsigned long frameID;
  int dataSize=0;  //为了提高性能
};

class sync_alg
{
  public:
    sync_alg(int device_num,int buffer_num);
    virtual ~sync_alg();
    //设置获取结果的回调函数，注意这里回调函数完成后，数据不要释放
    void setResultCallback(std::function<void(const std::vector<ImageType>&)>);
    void InputImage(ImageType image,int camera_index);  //输入图像，算法会接管该对象所有权
    void Boot();  //用于延时初始化
  private:
    std::vector<ImageType> ResultList;

    //粗粒度锁，到时候优化
    std::mutex mutStoreDataList;
    using RefDataPos=std::list<BigImageType>::iterator;
    std::list<BigImageType> storeDataList;  //存储数据的列表
    RefDataPos insertPos;  //表示新加入数据的位置，在这个位置之后是新加入的数据

    typedef class std::map<unsigned long,bottleItemType> bottleType;  //定义桶队列类型
    bottleType::iterator itrBottleBegin; //在这个标记之前的是用于回收的
    bottleType itrDataQueue;  //桶队列
    std::function<void(const std::vector<ImageType>&)> funcResultCallback;  //结果的回调函数
    
    std::jthread workThread;  //因为要频繁的释放修改内存，这里开一个线程专门跑算法
    void workFunction(std::stop_token stoken);  //算法在这函数里面
    std::condition_variable cvNewData;   //用于等待新数据
    pthread_t threadID;
    
    //设备数量，缓冲数量
    int device_num,buffer_num;
};

#endif
